/*!
 * 界面视图模块  
 */
layui.extend({
    jm: 'lib/extend/sm4Util'
}).define(['jm'], function (exports) {
    var $ = layui.jquery,
        laytpl = layui.laytpl,
        layer = layui.layer,
        setter = layui.setter,
        device = layui.device(),
        hint = layui.hint()
        //对外接口
        ,
        view = function (id) {
            return new Class(id);
        },
        jm = layui.jm,
        SHOW = 'layui-show',
        LAY_BODY = 'LAY_app_body'

        //构造器
        , Class = function (id) {
            this.id = id;
            this.container = $('#' + (id || LAY_BODY));
        };
    //加载中
    view.loading = function (elem) {
        elem.append(
            this.elemLoad = $('<i class="layui-anim layui-anim-rotate layui-anim-loop layui-icon layui-icon-loading layadmin-loading"></i>')
        );
    };
    //移除加载
    view.removeLoad = function () {
        this.elemLoad && this.elemLoad.remove();
    };

    //清除 token，并跳转到登入页
    view.exit = function () {
        //清空本地记录的 token
        layui.sessionData(setter.tableName + 'platform', {
            key: "platform",
            remove: true
        });
        layui.sessionData(setter.tableName, {
            key: setter.request.tokenName,
            remove: true
        });
        layui.sessionData(setter.tableName, {
            key: setter.request.RefreshToken,
            remove: true
        });
        layui.sessionData(setter.tableName, {
            key: 'ExpiredTime',
            remove: true
        });
        layui.sessionData(setter.tableName, {
            key: 'TimeSpan',
            remove: true
        });

        //跳转到登入页
        view(setter.container).render('login/index');
    };

    //Ajax请求
    view.req = function (options) {
        var that = this,
            success = options.success,
            error = options.error,
            request = setter.request,
            response = setter.response,
            debug = function () {
                return setter.debug ?
                    '<br><cite>URL：</cite>' + options.url :
                    '';
            };
        options.data = options.data || {};
        options.headers = options.headers || {};
        if (options.headers == 'undefined' || JSON.stringify(options.headers) == '{}') {
            if (request.tokenName) {
                //获取token
                var tokenNew = layui.sessionData(setter.tableName)[request.tokenName];
                var refresh = layui.sessionData(setter.tableName)[request.RefreshToken];
                //自动给 Request Headers 传入 token
                options.headers[request.tokenName] = layui.sessionData(setter.tableName)[setter.request.tokenName] ? "Bearer " + tokenNew : '';
                //判断是否需要传输刷新token，当距离过期时间超过80%时，自动传输刷新token
                // 获取时间参数（强制转换为数字类型）
                const tokenTime = Number(layui.sessionData(setter.tableName)['TimeSpan']);
                const expDuration = Number(layui.sessionData(setter.tableName)['ExpiredTime']);
                const currentTime = Date.now();

                // 参数有效性校验
                if (![tokenTime, expDuration, currentTime].some(isNaN)) {
                    // 计算阈值时间点（tokenTime + 80%过期时长）
                    const thresholdTime = tokenTime + expDuration*60000 * 0.8;
                    if (currentTime >= thresholdTime) {
                        //自动给 Request Headers 传入 用于刷新的token
                        options.headers[request.RefreshToken] = layui.sessionData(setter.tableName)[setter.request.RefreshToken] ? "Bearer " + refresh : '';
                    }

                }

            }
        }
        if (options.type == 'delete') {
            if (options.url.indexOf('https') == '-1') {
                // 不存在https
                options.url = setter.serverAdd + options.url + '?id=' + options.data.id;
            } else {
                options.url = options.url + '?id=' + options.data.id;
            }
            options.data = {};
        } else {
            if (options.url.indexOf('.') == -1) {
                options.url = setter.serverAdd + options.url + '?_=' + Math.random()
            }
        }
        delete options.success;
        delete options.error;
        return $.ajax($.extend({
            type: 'get',
            dataType: 'json',
            success: function (res, statusCode, xhr) {
                //这里判断是否要更新授权
                if (xhr.getResponseHeader('access-token')) {
                    //更新授权token
                    layui.sessionData(setter.tableName, {
                        key: setter.request.tokenName,
                        value: xhr.getResponseHeader('access-token')
                    });
                }
                if (xhr.getResponseHeader('x-access-token')) {
                    //更新刷新授权token
                    layui.sessionData(setter.tableName, {
                        key: setter.request.RefreshToken,
                        value: xhr.getResponseHeader('x-access-token')
                    });
                    //更新授权时间
                    layui.sessionData(setter.tableName, {
                        key: 'TimeSpan',
                        value: Date.now()
                    });
                }
                if (statusCode == "success" && res.statuscode != 401 && res.statuscode != 403) {
                    if (res.successful) {
                        const isEncrypted = xhr.getResponseHeader('X-Encrypted') === 'true';
                        if (isEncrypted) {
                            res.data = JSON.parse(jm.s4.decryptData_ECB(res.data));
                        }
                        else {
                            res.data = res.data;
                        }
                    }
                    typeof options.done === 'function' && options.done(res);
                }
                //登录状态失效，清除本地 access_token，并强制跳转到登入页
                else if (statusCode == "success" && (res.statuscode == 401 || res.statuscode == 403)) {
                    var errorText = [
                        '<cite>Error：</cite> ' + (res[response.msgName] || '登录超期'), debug()
                    ].join('');
                    view.exit();
                }
                //其它异常
                else {
                    var errorText = [
                        '<cite>Error：</cite> ' + (res[response.msgName] || '系统异常，请重试'), debug()
                    ].join('');
                    view.error(errorText);
                }

                //只要 http 状态码正常，无论 response 的 code 是否正常都执行 success
                typeof success === 'function' && success(res);
            },
            error: function (e, code) {
                var errorText = [
                    '请求异常，请重试<br><cite>错误信息：</cite>' + code, debug()
                ].join('');
                view.error(errorText);

                typeof error === 'function' && error.apply(this, arguments);
            }
        }, options));
    };

    //弹窗
    view.popup = function (options) {
        var success = options.success,
            skin = options.skin;

        delete options.success;
        delete options.skin;

        return layer.open($.extend({
            type: 1,
            title: '提示',
            content: '',
            id: 'LAY-system-view-popup',
            skin: 'layui-layer-admin' + (skin ? ' ' + skin : ''),
            shadeClose: true,
            closeBtn: false,
            success: function (layero, index) {
                var elemClose = $('<i class="layui-icon" close>&#x1006;</i>');
                layero.append(elemClose);
                elemClose.on('click', function () {
                    layer.close(index);
                });
                typeof success === 'function' && success.apply(this, arguments);
            }
        }, options))
    };

    //异常提示
    view.error = function (content, options) {
        return view.popup($.extend({
            content: content,
            maxWidth: 300
            //,shade: 0.01
            ,
            offset: 't',
            anim: 6,
            id: 'LAY_adminError'
        }, options))
    };


    //请求模板文件渲染
    Class.prototype.render = function (views, params) {
        var that = this,
            router = layui.router();
        views = setter.views + views + setter.engine;

        $('#' + LAY_BODY).children('.layadmin-loading').remove();
        view.loading(that.container); //loading
        //请求模板
        $.ajax({
            url: views,
            type: 'get',
            dataType: 'html',
            data: {
                v: layui.cache.version
            },
            success: function (html) {
                html = '<div>' + html + '</div>';

                var elemTitle = $(html).find('title'),
                    title = elemTitle.text() || (html.match(/\<title\>([\s\S]*)\<\/title>/) || [])[1];

                var res = {
                    title: title,
                    body: html
                };

                elemTitle.remove();
                that.params = params || {}; //获取参数

                if (that.then) {
                    that.then(res);
                    delete that.then;
                }

                that.parse(html);
                view.removeLoad();

                if (that.done) {
                    that.done(res);
                    delete that.done;
                }

            },
            error: function (e) {
                view.removeLoad();

                if (that.render.isError) {
                    return view.error('请求视图文件异常，状态：' + e.status);
                };

                if (e.status === 404) {
                    that.render('template/tips/404');
                } else {
                    that.render('template/tips/error');
                }

                that.render.isError = true;
            }
        });
        return that;
    };

    //解析模板
    Class.prototype.parse = function (html, refresh, callback) {
        var that = this,
            isScriptTpl = typeof html === 'object' //是否模板元素
            ,
            elem = isScriptTpl ? html : $(html),
            elemTemp = isScriptTpl ? html : elem.find('*[template]'),
            fn = function (options) {
                var tpl = laytpl(options.dataElem.html()),
                    res = $.extend({
                        params: router.params
                    }, options.res);

                options.dataElem.after(tpl.render(res));
                typeof callback === 'function' && callback();

                try {
                    options.done && new Function('d', options.done)(res);
                } catch (e) {
                    console.error(options.dataElem[0], '\n存在错误回调脚本\n\n', e)
                }
            },
            router = layui.router();
        elem.find('title').remove();
        that.container[refresh ? 'after' : 'html'](elem.children());

        router.params = that.params || {};
        //遍历模板区块
        for (var i = elemTemp.length; i > 0; i--) {
            (function () {
                var dataElem = elemTemp.eq(i - 1),
                    layDone = dataElem.attr('lay-done') || dataElem.attr('lay-then') //获取回调
                    ,
                    url = laytpl(dataElem.attr('lay-url') || '').render(router) //接口 url
                    ,
                    data = laytpl(dataElem.attr('lay-data') || '').render(router) //接口参数
                    ,
                    headers = laytpl(dataElem.attr('lay-headers') || '').render(router); //接口请求的头信息

                try {
                    data = new Function('return ' + data + ';')();
                } catch (e) {
                    hint.error('lay-data: ' + e.message);
                    data = {};
                };

                try {
                    headers = new Function('return ' + headers + ';')();
                } catch (e) {
                    hint.error('lay-headers: ' + e.message);
                    headers = headers || {}
                };

                if (url) {
                    view.req({
                        type: dataElem.attr('lay-type') || 'get',
                        url: url,
                        data: data,
                        dataType: 'json',
                        headers: headers,
                        success: function (res) {
                            fn({
                                dataElem: dataElem,
                                res: res,
                                done: layDone
                            });
                        }
                    });
                } else {
                    fn({
                        dataElem: dataElem,
                        done: layDone
                    });
                }
            }());
        }
        return that;
    };

    //直接渲染字符
    Class.prototype.send = function (views, data) {
        var tpl = laytpl(views || this.container.html()).render(data || {});
        this.container.html(tpl);
        return this;
    };

    //局部刷新模板
    Class.prototype.refresh = function (callback) {
        var that = this,
            next = that.container.next(),
            templateid = next.attr('lay-templateid');

        if (that.id != templateid) return that;

        that.parse(that.container, 'refresh', function () {
            that.container.siblings('[lay-templateid="' + that.id + '"]:last').remove();
            typeof callback === 'function' && callback();
        });

        return that;
    };

    //视图请求成功后的回调
    Class.prototype.then = function (callback) {
        this.then = callback;
        return this;
    };

    //视图渲染完毕后的回调
    Class.prototype.done = function (callback) {
        this.done = callback;
        return this;
    };
    //对外接口
    exports('view', view);
});